package com.aqielife.demo.webflux.router;


import org.springframework.http.MediaType;
import org.springframework.http.codec.ServerSentEvent;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import reactor.core.publisher.Flux;
import reactor.util.function.Tuples;

import java.time.Duration;

/**
 * @author aqie
 * @date 2022/02/05 22:50
 * @desc
 */
@Controller
@RequestMapping("/sse")
public class SseController {

  //三分钟倒计时
  private int count_down_sec=3*60*60;

  /**
   * 推送页面1
   * @return
   */
  @GetMapping
  public String sse(){
    return "sse";
  }

  /**
   * 推送页面2
   * @return
   */
  @GetMapping("/two")
  public String sse2(){
    return "sse2";
  }

  /**
   * 推送页面3
   * @return
   */
  @GetMapping("/three")
  public String sse3(){
    return "sse3";
  }

  /**
   * 推送页面4
   * @return
   */
  @GetMapping("/four")
  public String sse4(){
    return "sse4";
  }

  //报头设置为 "text/event-stream"，以便于发送事件流
  @GetMapping(value="/countDown",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
  @ResponseBody
  public Flux<ServerSentEvent<Object>> countDown() {
    //每一秒钟推送一次
    return Flux.interval(Duration.ofSeconds(1))
    .map(seq -> Tuples.of(seq, getCountDownSec()))
    .map(data -> ServerSentEvent.<Object>builder()
    .event("countDown") //和前端addEventListener监听的事件一一对应
    .id(Long.toString(data.getT1()))  //为每次发送设置一个id
    .data(data.getT2().toString())
    .build());
  }

  private String getCountDownSec() {
    if (count_down_sec>0) {
      int h = count_down_sec/(60*60);
      int m = (count_down_sec%(60*60))/60;
      int s = (count_down_sec%(60*60))%60;
      count_down_sec--;
      return "活动倒计时："+h+" 小时 "+m+" 分钟 "+s+" 秒";
    }
    return "活动倒计时：0 小时 0 分钟 0 秒";
  }

  //报头设置为 "text/event-stream"，以便于发送事件流,这种写法等同于MediaType.TEXT_EVENT_STREAM_VALUE "text/event-stream;charset=UTF-8"
  @GetMapping(value = "/retrieve",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
  @ResponseBody
  public double retrieve() {
    try {
      //每0.5秒刷新数据
      Thread.sleep(500);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
    //模拟股票实时变动数据
    return Math.ceil(Math.random() * 10000);
  }
}
